use log::error;
use redis::{FromRedisValue, RedisResult, RedisWrite, ToRedisArgs, Value};
use serde::de::DeserializeOwned;
use serde::Serialize;

/// redis的响应结果
pub struct RedisJson<T>(pub T);
impl<T> FromRedisValue for RedisJson<T>
where
    T: DeserializeOwned,
{
    fn from_redis_value(v: &Value) -> RedisResult<Self> {
        match v {
            // Value::SimpleString(data) => {
            //     let result = serde_json::from_str(&data);
            //     match result {
            //         Ok(v) => Ok(JsonValue(v)),
            //         Err(e) => Err(RedisError::from(e)),
            //     }
            // },
            Value::Nil => {
                Err((redis::ErrorKind::ResponseError, "数据不存在").into())
            },
            Value::BulkString(data) => {
                let value = std::str::from_utf8(data)?;
                let result = serde_json::from_str(value);
                match result {
                    Ok(v) => Ok(RedisJson(v)),
                    Err(e) =>{
                        error!("json反序列化错误：{e}");
                        Err((redis::ErrorKind::ParseError, "json解析错误").into())
                    },
                }
            }
            _ => Err((redis::ErrorKind::TypeError, "类型错误").into()),
        }
    }
}

impl<T> ToRedisArgs for RedisJson<T>
where
    T: Serialize,
{
    fn write_redis_args<W>(&self, out: &mut W)
    where
        W: ?Sized + RedisWrite,
    {
        serde_json::to_string(&self.0)
            .expect("序列化错误")
            .write_redis_args(out)
    }
}


/// redis的响应结果(结果是Option类型)
pub struct RedisOptionJson<T>(pub Option<T>);
impl<T> FromRedisValue for RedisOptionJson<T>
where
    T: DeserializeOwned,
{
    fn from_redis_value(v: &Value) -> RedisResult<Self> {
        match v {
            Value::Nil => {
                Ok(RedisOptionJson(None))
            },
            Value::BulkString(data) => {
                let value = std::str::from_utf8(data)?;
                let result = serde_json::from_str(value);
                match result {
                    Ok(v) => Ok(RedisOptionJson(Some(v))),
                    Err(e) => {
                        error!("json反序列化错误：{e}");
                        Err((redis::ErrorKind::ParseError, "json解析错误").into())
                    },
                }
            }
            _ => Err((redis::ErrorKind::TypeError, "类型错误").into()),
        }
    }
}